/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package hirt;

import java.nio.ByteBuffer;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Communication Actions serve 2 purposes
 * They are used to send send chat messages back and forth across the network
 * and used to send player request, i.e. asking another player to move a car
 * @author zamille
 */
public class CommunicationAction extends Action
{
    /** Chat message or Request Message possible types
     * found in static members of CommunicationAction*/
    protected byte type;
    /** The message being transmitted*/
    protected String message;
    /** the item the message is directed at.
     * Only applicable in requests
     */
    protected Item recipiant;

    protected static final byte TYPE_CHAT = 0;
    protected static final byte TYPE_REQUESTMOVE = 1;
    protected static final byte TYPE_REQUESTCAR = 2;

    /**
     *
     */
    public CommunicationAction()
    {
        super();
        type = TYPE_CHAT;
        message = "";
        recipiant = null;
        super.messageType = Message.CHAT_MESSAGE;
    }

    /**
     *
     * @param actor
     * @param text
     */
    public CommunicationAction(Item actor, String text)
    {
        super(actor);
        message = text;
        type = TYPE_CHAT;
        recipiant = null;
        super.messageType = Message.CHAT_MESSAGE;
    }

    /**
     *
     * @param actor
     * @param start
     * @param text
     */
    public CommunicationAction(Item actor, double start, String text)
    {
        super(actor, start, 0);
        message = text;
        type = TYPE_CHAT;
        recipiant = null;
        super.messageType = Message.CHAT_MESSAGE;
    }

    /**
     *
     * @param actor
     * @param start
     * @param text
     * @param reciever
     */
    public CommunicationAction(Item actor, double start, String text, Item reciever)
    {
        super(actor, start, 0);
        message = text;
        type = TYPE_CHAT;
        recipiant = reciever;
        super.messageType = Message.CHAT_MESSAGE;
    }

    /**
     *
     * @param actor
     * @param start
     * @param text
     * @param reciever
     * @param messageType
     */
    public CommunicationAction(Item actor, double start, String text, Item reciever, byte messageType)
    {
        super(actor, start, 0);
        message = text;
        setType(messageType);
        recipiant = reciever;
        super.messageType = Message.CHAT_MESSAGE;
    }

    /**
     * Builds an Action from a byte stream, presumably created by an action across the network
     * this action should be identical to that one
     * @param bytes
     * @param items: Master Item List used to build the action
     */
    public CommunicationAction(ByteBuffer bytes, Vector<Item> items)
    {
       fromByte(bytes,items);
    }

    /**
     * Builds an Action from a save string, presumably read from a save
     * this action should be identical to the one saved in the file
     * @param save string
     * @param items: Master Item List used to build the action
     * @return what's left of the parem SaveString after this methods completes
     */
    public CommunicationAction(String text, Vector<Item> items)
    {
        fromSaveString(text,items);
    }

    /**
     * Builds an Action from a byte stream, presumably created by an action across the network
     * this action should be identical to that one
     * @param bytes
     * @param items: Master Item List used to build the action
     * @return what's left of the parem bytes after this methods completes
     */
    public ByteBuffer fromByte(ByteBuffer bytes, Vector<Item> items)
    {
        bytes =  super.fromBytes(bytes, items);   //it uses the inherited method to build
        type = bytes.get(0);                    //the inherited members from the ByteBuffer
        int index = bytes.getInt(1);
        recipiant = ByteChanger.getItem(bytes, items, 1);
        int length = bytes.getInt(5);
        message = ByteChanger.getString(bytes, 9, length);
        super.messageType = Message.CHAT_MESSAGE;
        try {
            bytes = ByteChanger.truncate(bytes, 9 + length);
        } catch (Exception ex) {
            Logger.getLogger(CommunicationAction.class.getName()).log(Level.SEVERE, null, ex);
        }
        return bytes;

    }

    public String getMessage()
    {
        return message;
    }

    public void setMessage(String message)
    {
        this.message = message;
    }

    public int getType()
    {
        return type;
    }

    public void setType(byte messageType)
    {
        if (messageType >= TYPE_CHAT && messageType <= TYPE_REQUESTCAR)
            this.type = messageType;
    }

    public Item getRecipiant()
    {
        return recipiant;
    }

    public void setRecipiant(Item recipiant)
    {
        this.recipiant = recipiant;
    }

    public boolean isBroadcast()
    {
        return recipiant == null;
    }

    /**
     * Returns a ByteBuffer representation of this Action
     * Used to send actions over the network
     * @return ByteBuffer
     */
    @Override
    public ByteBuffer toByte()
    {
        ByteBuffer buf = super.toByte();   //it uses the inherited method to put
        buf.put(type);                  //the inherited members in the ByteBuffer
        buf.putInt(ByteChanger.itemToByte(recipiant));
        buf.putInt(message.length());
        buf.put(message.getBytes());
        return buf;
    }

    /**
     * Returns a String representation of this Action
     * Used to save this action to a file
     * @return Save String
     */
    @Override
    public String toSaveString()
    {
        String text = super.toSaveString();   //it uses the inherited method to put
        text += type  + "\t";           //the inherited members in the Save String
        text += ByteChanger.itemToByte(recipiant) + "\t";
        text += message  + "\t";
        return text;
    }

    /**
     * Builds an Action from a save string, presumably read from a save
     * this action should be identical to the one saved in the file
     * @param save string
     * @param items: Master Item List used to build the action
     * @return what's left of the parem SaveString after this methods completes
     */
    @Override
    protected String fromSaveString(String text, Vector<Item> items)
    {
        text = super.fromSaveString(text, items);   //it uses the inherited method to put
        String substring = ByteChanger.getNextValue(text);  //the inherited members from the Save String
        type = Byte.parseByte(substring);

        text = ByteChanger.incrementString(text);
        substring = ByteChanger.getNextValue(text);
        recipiant = ByteChanger.getItem(substring, items);

        text = ByteChanger.incrementString(text);
        substring = ByteChanger.getNextValue(text);
        message = substring;

        text = ByteChanger.incrementString(text);
        return text;
    }

}
